<!DOCTYPE html>
<html lang="zh-cn">

<head>
  <meta charset="utf-8">
  <title>Java后端WebSocket的Tomcat实现</title>
  <script src="../static/js/jquery.min.js"></script>
</head>

<body>
<div id="message"></div>
<hr />
<div id="main"></div>
<div id="client"></div>
<label for="sidsTo">
  <input id="sidsTo" placeholder="输入要发送用户的SessionId">
</label>
<label for="text">
  <input id="text" type="text" />
</label>
<button onclick="send()">发送消息</button>
<button onclick="openOrCloseWebSocket()">打开/关闭WebSocket连接</button>
<hr />
</body>
<script type="text/javascript">

  const cid = Math.floor(Math.random() * 100); // 随机生成客户端id
  document.getElementById('client').innerHTML += "客户端 id = " + cid + '<br/>';

  let websocket;
  // 定时任务
  let tt;
  //是否关闭
  let isWebSocketClosed = true;
  // 避免重复连接
  let lockReconnect = false;

  //打开/关闭WebSocket连接
  function openOrCloseWebSocket() {
    if(isWebSocketClosed){
      createWebSocket();
    }else {
      websocket.close();
      isWebSocketClosed = true;
      alert('websocket.close: 关闭websocket连接')
    }
  }

  function createWebSocket() {
    try{
      //判断当前浏览器是否支持WebSocket
      if ('WebSocket' in window) {
        // 改成你的地址
        websocket = new WebSocket("ws://127.0.0.1:8080/api/websocket/" + cid);
        init();
      } else {
        alert('当前浏览器 Not support websocket')
      }
    } catch(e) {
      console.log('catch' + e);
      reconnect();
    }
  }

  function init() {
    //连接发生错误的回调方法
    websocket.onerror = function () {
      setMessageInnerHTML(new Date().toLocaleString() + " websocket.onerror: WebSocket连接发生错误");
    };

    //连接成功建立的回调方法
    websocket.onopen = function () {
      isWebSocketClosed = false;
      setMessageInnerHTML(new Date().toLocaleString() + " websocket.onopen: WebSocket连接成功");
    }

    //接收到消息的回调方法
    websocket.onmessage = function (event) {
      setMessageInnerHTML(new Date().toLocaleString() + " websocket.onmessage: " + event.data);
    }

    //连接关闭的回调方法
    websocket.onclose = function (e) {
      console.log(new Date().toLocaleString() + ' 连接关闭' + e.code);
      // 服务器关闭  不重连
      if (e.code !== 1000){
        reconnect();
      }
      setMessageInnerHTML(new Date().toLocaleString() + " websocket.onclose: WebSocket连接关闭");
    }

  }

  function reconnect() {
    if(lockReconnect) {
      return;
    }
    lockReconnect = true;
    //没连接上会一直重连，设置延迟避免请求过多，  有定时任务 先取消再设置
    tt && clearTimeout(tt);
    tt = setTimeout(function () {
      createWebSocket();
      lockReconnect = false;
    }, 2000);
  }

  //将消息显示在网页上
  function setMessageInnerHTML(innerHTML) {
    document.getElementById('message').innerHTML += innerHTML + '<br/>';
  }

  //监听窗口关闭事件，当窗口关闭时，主动去关闭websocket连接，防止连接还没断开就关闭窗口，server端会抛异常。
  window.onbeforeunload = function () {
    closeWebSocket();
  }

  //发送消息
  function send() {
    const sidsTo = document.getElementById('sidsTo').value;
    const message = document.getElementById('text').value;
    try {
      const obj = {};
      obj.sidsTo = sidsTo.split(",");
      obj.message = message;
      websocket.send(JSON.stringify(obj));
      setMessageInnerHTML(new Date().toLocaleString() + " websocket.send: " + message);
    } catch (err) {
      console.error("websocket.send: " + message + " 失败");
    }
  }
</script>

</html>